@echo off
REM 一键上传脚本：自动检测并上传同目录下所有 Git 仓库的更改到远程仓库

setlocal enabledelayedexpansion

REM 记录并切换控制台编码，避免中文提示乱码
for /f "tokens=2 delims=: " %%f in ('chcp') do set "_OLD_CODE_PAGE=%%f"
chcp 65001 >nul

REM 检查 Git 是否可用
git --version >nul 2>&1
if errorlevel 1 (
    echo ❌ Git 未安装或不可用，请先安装 Git。
    goto :cleanup
)

REM 获取脚本所在目录
set "SCRIPT_DIR=%~dp0"

REM 检查当前目录是否为 Git 仓库
if exist "%SCRIPT_DIR%.git" (
    echo 🔍 发现当前目录是 Git 仓库，直接使用当前目录
    set "REPO_DIR=%SCRIPT_DIR%"
    goto :process_repo
)

REM 自动检测同目录下的 Git 仓库
echo 🔍 正在自动检测同目录下的 Git 仓库...
set "FOUND_REPOS="
set "REPO_COUNT=0"

for /d %%D in ("%SCRIPT_DIR%*") do (
    if exist "%%D\.git" (
        set /a REPO_COUNT+=1
        if !REPO_COUNT! EQU 1 (
            set "FIRST_REPO=%%D"
        )
        echo    发现仓库 !REPO_COUNT!: %%~nD
        set "FOUND_REPOS=!FOUND_REPOS! %%D"
    )
)

if %REPO_COUNT% EQU 0 (
    echo ❌ 未找到任何 Git 仓库。
    echo 💡 请确保脚本与 Git 仓库在同一目录下，或在 Git 仓库中运行此脚本。
    goto :cleanup
) else if %REPO_COUNT% EQU 1 (
    echo ✅ 找到 1 个仓库，自动选择: %FIRST_REPO%
    set "REPO_DIR=%FIRST_REPO%"
) else (
    echo.
    echo 🤔 找到 %REPO_COUNT% 个 Git 仓库，请选择要操作的仓库:
    set "COUNTER=0"
    for %%R in (%FOUND_REPOS%) do (
        set /a COUNTER+=1
        echo    !COUNTER!. %%~nR
        set "REPO_!COUNTER!=%%R"
    )
    echo.
    :select_repo
    set /p "REPO_CHOICE=请输入仓库编号 (1-%REPO_COUNT%): "
    if "!REPO_CHOICE!"=="" goto :select_repo
    if !REPO_CHOICE! LSS 1 goto :select_repo
    if !REPO_CHOICE! GTR %REPO_COUNT% goto :select_repo
    
    call set "REPO_DIR=%%REPO_!REPO_CHOICE!%%"
    echo ✅ 选择了仓库: !REPO_DIR!
)

:process_repo

pushd "%REPO_DIR%"
echo.
echo 📂 当前工作目录: %REPO_DIR%
echo ==========================================

REM 帮助构造符合 Conventional Commits 的提交信息
set "COMMIT_MSG=%~1"

if not "%COMMIT_MSG%"=="" (
    call :ValidateCommitMessage "%COMMIT_MSG%"
    if not defined MESSAGE_IS_VALID (
        echo ⚠️ 检测到提交信息不符合 Conventional Commits 规范，将进入交互式输入。
        set "COMMIT_MSG="
    )
)

if "%COMMIT_MSG%"=="" (
    call :PromptCommitMessage
)

echo 最终提交信息：%COMMIT_MSG%


echo 正在检查仓库状态...
git status --porcelain >nul 2>&1
if errorlevel 1 (
    echo ❌ 无法获取仓库状态。
    goto :error
)

REM 检查是否有未提交的更改
for /f %%i in ('git status --porcelain') do set "HAS_CHANGES=1"
if not defined HAS_CHANGES (
    echo ℹ️ 没有需要提交的更改。
    goto :success
)

echo 正在执行 git add .
git add .
if errorlevel 1 (
    echo ❌ git add 失败。
    goto :error
)

echo 正在执行 git commit -m "%COMMIT_MSG%"
git commit -m "%COMMIT_MSG%"
if errorlevel 1 (
    echo ❌ git commit 失败，可能没有更改或提交消息无效。
    goto :error
)

echo 正在执行 git pull --rebase
git pull --rebase
if errorlevel 1 (
    echo.
    echo ❌ git pull --rebase 失败，检测到冲突或其他问题。
    echo.
    git status
    echo.
    echo 冲突处理建议：
    echo   1. 如需跳过当前冲突提交：git rebase --skip
    echo   2. 如需手动解决冲突后继续：git add . ^& git rebase --continue
    echo   3. 如需放弃 rebase 回到之前状态：git rebase --abort
    echo.
    echo 请手动处理后重新运行脚本。
    goto :error
)

echo 正在执行 git push
git push
if errorlevel 1 (
    echo ❌ git push 失败，可能没有推送权限或远程仓库问题。
    goto :error
)

:success
echo.
echo ✅ 上传成功！
goto :end

:ValidateCommitMessage
set "MESSAGE_IS_VALID="
if "%~1"=="" goto :eof
echo %~1 | findstr /C:": " >nul || goto :eof
for /f "tokens=1 delims=:" %%A in ("%~1") do set "COMMIT_TYPE_RAW=%%~A"
set "COMMIT_TYPE_RAW=%COMMIT_TYPE_RAW: =%"
if "%COMMIT_TYPE_RAW%"=="" goto :eof
for /f "tokens=1 delims=(" %%B in ("%COMMIT_TYPE_RAW%") do set "COMMIT_TYPE=%%~B"
if "%COMMIT_TYPE%"=="" set "COMMIT_TYPE=%COMMIT_TYPE_RAW%"
for %%T in (feat fix docs style refactor perf test build ci chore revert) do (
    if /I "%COMMIT_TYPE%"=="%%T" set "MESSAGE_IS_VALID=1"
)
goto :eof

:PromptCommitMessage
echo 请选择提交类型（回车默认 fix）：
echo    feat     - 新功能
echo    fix      - 缺陷修复
echo    docs     - 文档调整
echo    style    - 代码风格（无业务逻辑改动）
echo    refactor - 重构
echo    perf     - 性能优化
echo    test     - 测试相关
echo    build    - 构建系统
echo    ci       - CI 配置
echo    chore    - 其他杂务
echo    revert   - 回滚提交
set /p "COMMIT_TYPE=类型[type]: "
if "%COMMIT_TYPE%"=="" set "COMMIT_TYPE=fix"

set "VALID_TYPE="
for %%T in (feat fix docs style refactor perf test build ci chore revert) do (
    if /I "%COMMIT_TYPE%"=="%%T" set "VALID_TYPE=1"
)
if not defined VALID_TYPE (
    echo ❌ 无效的类型，请重新输入。
    set "COMMIT_TYPE="
    goto :PromptCommitMessage
)

set /p "COMMIT_SCOPE=可选作用域(scope，可留空): "

:prompt_subject
set /p "COMMIT_SUBJECT=提交说明(subject，必须填写): "
if "%COMMIT_SUBJECT%"=="" (
    echo ❌ 提交说明不能为空，请重新输入。
    goto :prompt_subject
)

if "%COMMIT_SCOPE%"=="" (
    set "COMMIT_MSG=%COMMIT_TYPE%: %COMMIT_SUBJECT%"
) else (
    set "COMMIT_MSG=%COMMIT_TYPE%(%COMMIT_SCOPE%): %COMMIT_SUBJECT%"
)
goto :eof

:error
echo.
echo ❌ 操作失败，请检查上面的错误信息。

:end
popd

:cleanup
pause
if defined _OLD_CODE_PAGE chcp %_OLD_CODE_PAGE% >nul
endlocal
